#include <Python.h>
#include <atomic>
#include "pyobjautoptr.h"
pyobjautoptr::pyobjautoptr(PyObject* obj): res(obj){
    if (res) {
        Py_INCREF(res);
    }
}

pyobjautoptr::~pyobjautoptr()noexcept {
    if (res) {
        if (res->ob_type != NULL) {
            if (Py_REFCNT(res) < 2) {
                Py_DECREF(res);
            }
        }
    }
}

pyobjautoptr::pyobjautoptr(const pyobjautoptr& other)noexcept : res(other.res){
        if (res)
            Py_INCREF(res);
}

pyobjautoptr& pyobjautoptr::operator=(const pyobjautoptr& other)noexcept {
        if (this != &other) {
            if (res)
                Py_DECREF(res);

            res = other.res;

            if (res)
                Py_INCREF(res);
        }
        return *this;
}

pyobjautoptr::pyobjautoptr(pyobjautoptr&& other) noexcept : res(other.res) {
        other.res = nullptr;
}

pyobjautoptr& pyobjautoptr::operator=(pyobjautoptr&& other)noexcept {
        if (this != &other) {
            if (res)
                Py_DECREF(res);

            res = other.res;
            other.res = nullptr;
        }
        return *this;
}

pyobjautoptr::operator PyObject* () const noexcept {
        Py_INCREF(res);
        return res;
}

PyObject* pyobjautoptr::get() const noexcept {
        Py_INCREF(res);
        return res;
}
pyobjautoptr& pyobjautoptr::operator=(const PyObject*& other)noexcept {
    auto tmp = const_cast<PyObject*>(other);
    this->res = tmp;
    Py_INCREF(res);
    return *(this);
}
pyobjautoptr& pyobjautoptr::operator=(PyObject*& other)noexcept {
    PyObject* tmp = other;
    this->res = tmp;
    Py_INCREF(res);
    return *(this);
}